package com.car.loan.project.xr.service.impl;

import com.car.loan.common.exception.loan.LoanParameterException;
import com.car.loan.common.utils.SecurityUtils;
import com.car.loan.common.utils.StringUtils;
import com.car.loan.framework.web.domain.AjaxResult;
import com.car.loan.project.cm.domain.CmBank;
import com.car.loan.project.cm.mapper.CmBankMapper;
import com.car.loan.project.xr.domain.Loan;
import com.car.loan.project.xr.domain.LoanDetail;
import com.car.loan.project.xr.domain.LoanExt;
import com.car.loan.project.xr.domain.LoanStatus;
import com.car.loan.project.xr.mapper.LoanDetailMapper;
import com.car.loan.project.xr.mapper.LoanExtMapper;
import com.car.loan.project.xr.mapper.LoanMapper;
import com.car.loan.project.xr.mapper.LoanStatusMapper;
import com.car.loan.project.xr.util.bo.business.RepaymentInfoBo;
import com.car.loan.project.xr.util.enums.RepaymentInfoStatus;
import com.car.loan.project.xr.util.repayment.RepaymentFormulaInterface;
import com.car.loan.project.xr.util.repayment.RepaymentInfo;
import com.car.loan.project.xr.util.repayment.RepaymentInfoParam;
import com.car.loan.project.xr.util.repayment.RepaymentPlanUtil;
import java.math.BigDecimal;
import java.math.MathContext;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author huangding
 * @description
 * @date 2019/12/22 22:00
 */
@Service
public class RepaymentInfoService {


    @Autowired
    private LoanExtMapper loanExtMapper;

    @Autowired
    private LoanDetailMapper loanDetailMapper;

    @Autowired
    private Map<String, RepaymentFormulaInterface> repaymentFormulaInterfaceMap;

    @Autowired
    private LoanStatusMapper loanStatusMapper;

    @Autowired
    private CmBankMapper cmBankMapper;

    @Autowired
    private LoanMapper loanMapper;


    /**
     * @param loanId 业务id
     * @param lendDate 放贷时间
     * @param statementDay 账单日
     */
    public AjaxResult getRepaymentInfo(Long loanId, String lendDate, Integer statementDay) {
        Loan loan = loanMapper.selectById(loanId);
        if (null == loan) {
            return AjaxResult.error("业务不存在");
        }
        Long bankId = loan.getBankId();
        CmBank cmBank = cmBankMapper.selectById(bankId);
        if (null == cmBank) {
            return AjaxResult.error("银行不存在");
        }

        if (StringUtils.isEmpty(cmBank.getRepaymentFormula())) {
            return AjaxResult.error("该银行还款公式未实现");
        }

        RepaymentFormulaInterface repaymentFormulaInterface = repaymentFormulaInterfaceMap
            .get(cmBank.getRepaymentFormula());

        RepaymentInfoParam repaymentInfoParam = new RepaymentInfoParam();
        repaymentInfoParam.setLendDate(lendDate);
        repaymentInfoParam.setStatementDay(statementDay);

        Optional<LoanExt> optionalLoanExt = loanExtMapper.selectByLoanId(loanId);
        LoanExt loanExt = optionalLoanExt.get();

        if (loanExt.getInstallmentAmount() > loanExt.getFinancingAmount()) {
            RepaymentInfo repaymentInfo = new RepaymentInfo();
            repaymentInfo.setFirstStatementDate(RepaymentPlanUtil
                .getFirstStatementDate(repaymentInfoParam.getLendDate(),
                    repaymentInfoParam.getStatementDay()));
            return AjaxResult.success(repaymentInfo);
        }

        repaymentInfoParam.setFinancingAmount(new BigDecimal(loanExt.getFinancingAmount()));
        repaymentInfoParam.setInstallmentAmount(new BigDecimal(loanExt.getInstallmentAmount()));
        repaymentInfoParam
            .setRate(new BigDecimal(loanExt.getBankRate())
                .divide(new BigDecimal(100), MathContext.DECIMAL128));
        repaymentInfoParam.setTerm(Integer.valueOf(loanExt.getTerm().toString()));
        repaymentInfoParam.setGracePeriod(cmBank.getGracePeriod());
        RepaymentInfo repaymentInfo = repaymentFormulaInterface
            .getRepaymentInfo(repaymentInfoParam);

        repaymentInfo.setLastRepaymentDate(RepaymentPlanUtil
            .getLastRepaymentDate(cmBank.getGracePeriod(), loanExt.getTerm(),
                repaymentInfo.getFirstStatementDate()));
        return AjaxResult.success(repaymentInfo);
    }


    @Transactional(rollbackFor = Exception.class)
    public AjaxResult input(RepaymentInfoBo repaymentInfoBo) {
        long loanId = Long.parseLong(repaymentInfoBo.getLoanId());
        Optional<LoanStatus> optionalLoanStatus = loanStatusMapper.selectByLoanId(loanId);
        LoanStatus loanStatus = optionalLoanStatus
            .orElseThrow(() -> new LoanParameterException("该业务状态数据异常，请联系管理员"));

        Long repaymentInfoStatus = loanStatus.getRepaymentInfoStatus();
        if (RepaymentInfoStatus.INIT.status != repaymentInfoStatus) {
            return AjaxResult.error("当前状态不可提交");
        }
        loanStatus.setRepaymentInfoStatus(repaymentInfoBo.getOperatorStatus());
        loanStatus.setRepaymentInfoTime(LocalDateTime.now());
        loanStatus.setRepaymentInfoId(SecurityUtils.getLoginUserId());
        loanStatusMapper.updateById(loanStatus);

        Optional<LoanDetail> optionalLoanDetail = loanDetailMapper.selectByLoanId(loanId);
        LoanDetail loanDetail = optionalLoanDetail.get();
        loanDetail.setLendDate(repaymentInfoBo.getLendDate());
        loanDetail.setFirstRepayDate(repaymentInfoBo.getFirstRepayDate());
        loanDetail.setMonthRepayInterest(repaymentInfoBo.getMonthRepayInterest());
        loanDetail.setMonthRepayPrincipal(repaymentInfoBo.getMonthRepayPrincipal());
        loanDetail.setFirstRepayInterest(repaymentInfoBo.getFirstRepayInterest());
        loanDetail.setFirstRepayPrincipal(repaymentInfoBo.getFirstRepayPrincipal());
        loanDetail.setLastRepayInterest(repaymentInfoBo.getLastRepayInterest());
        loanDetail.setLastRepayPrincipal(repaymentInfoBo.getLastRepayPrincipal());
        loanDetail.setLastRepaymentDate(repaymentInfoBo.getLastRepaymentDate());

        if (StringUtils.isNotEmpty(repaymentInfoBo.getRepayCardNo())) {
            loanDetail.setRepayCardNo(repaymentInfoBo.getRepayCardNo().replace(" ", ""));
        }
        if (StringUtils.isNotEmpty(repaymentInfoBo.getDeductionCardNo())) {
            loanDetail.setDeductionCardNo(repaymentInfoBo.getDeductionCardNo().replace(" ", ""));
        }
        loanDetailMapper.updateById(loanDetail);
        return AjaxResult.success();
    }


}
